#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fonctions.h"

/* Global */
void ecrireCode(char* inputFileName)
{
    printf("Ecriture du code MIPS : DEBUT\n");
    FILE* yyout = fopen(inputFileName,"w");
    free(inputFileName);
    fprintf(yyout,"# Fichier généré automatiquement par TIASC\n");
    fprintf(yyout,"\n");
    // Segment DATA
    fprintf(yyout,"\t.data\n");

    // Ecriture des strings constants
    if (strings != NULL)
    {
        s_cell* s = strings->first;
        while (s != NULL)
        {
            fprintf(yyout,"str%d : .asciiz %s\n", s->index, s->string);
            s = s->next;
        }
        detruireList(strings);
    }
    //fprintf(yyout,"true : .asciiz \"true\"\n");
    //fprintf(yyout,"false : .asciiz \"false\"\n");
    fprintf(yyout,"line : .asciiz \"\\n\"\n");
    
    // Segment TEXT
    fprintf(yyout,"\t.text\n");
    
    //Ecriture des fonctions
    if (tab_symb != NULL)
    {
		s_symbole* symb = tab_symb->first;
		while (symb != NULL)
		{
			if (symb->type == TYPE_FONCTION)
			{
				fprintf(yyout,"f%d :\n",symb->fonction->index);
				if (symb->fonction->quads != NULL)
				{
					s_quadnext* qn = symb->fonction->quads->first;
					while(qn!=NULL)
					{
						ecrirequad(yyout, qn->q, symb->fonction->index);
						qn = qn->next;
					}
				}
	/*			//Enlever les symboles
				int nbSymboles = 0;
				if (symb->fonction->tab_symb_locale!= NULL)
				{
					s_symbole* symb_local = symb->fonction->tab_symb_locale->first;
					while (symb_local != NULL)
					{
						nbSymboles++;
						symb_local = symb_local->next;
					}
				} 
				if (nbSymboles != 0)
				{
					fprintf(yyout, "\tadd $sp,$sp,%d\n", nbSymboles*4);
				}*/
				//return
				fprintf(yyout,"jal $ra\n");
			}
			symb = symb->next;
		}
	}
    
    fprintf(yyout,".globl main\n");
    fprintf(yyout,"main :\n");


    if (quads != NULL)
    {
        s_quadnext* qn = quads->first;
        while(qn!=NULL)
        {
            ecrirequad(yyout, qn->q, -1);
            qn = qn->next;
        }
    }

    //Pour terminer proprement
    fprintf(yyout,"l%d :\n",quads->last->q->index+1);
    fprintf(yyout,"#exit\n");
    fprintf(yyout,"\tli $v0 10\n");
    fprintf(yyout,"\tsyscall\n");

    fclose(yyout);
    printf("Ecriture du code MIPS : FINI\n");
}
void ecrirequad(FILE* file, s_quad* q, int idx_fonction)
{
	if (idx_fonction == -1)
	{
		fprintf(file, "l%d :\n", q->index);
	}
	else
	{
		fprintf(file, "f%dl%d :\n", idx_fonction, q->index);
	}
    if (q->type == WRITE_STRING || q->type == WRITELN_STRING)
    {
        if (q->type == WRITE_STRING) fprintf(file,"#write string\n");
        else fprintf(file,"#writeln string\n");
        fprintf(file,"\tli $v0,4\n");
        fprintf(file,"\tla $a0,str%d\n",q->arg1);
        fprintf(file,"\tsyscall\n");
        if (q->type == WRITELN_STRING)
        {
            fprintf(file,"\tli $v0,4\n");
            fprintf(file,"\tla $a0,line\n");
            fprintf(file,"\tsyscall\n");
        }
    }
    else if (q->type == WRITE_CST_INT || q->type == WRITELN_CST_INT)
    {
        if (q->type == WRITE_CST_INT) fprintf(file,"#write cst int\n");
        else fprintf(file,"#writeln cst int\n");
        fprintf(file,"\tlw $a0,%d($sp)\n",q->arg1);
        fprintf(file,"\tli $v0,1\n");
        fprintf(file,"\tsyscall\n");
        if (q->type == WRITELN_CST_INT)
        {
            fprintf(file,"\tli $v0,4\n");
            fprintf(file,"\tla $a0,line\n");
            fprintf(file,"\tsyscall\n");
        }
    }
    else if (q->type == WRITE_INT || q->type == WRITELN_INT)
    {
        if (q->type == WRITE_INT) fprintf(file,"#write int\n");
        else fprintf(file,"#writeln int\n");
        fprintf(file,"\tlw $a0,%d($sp)\n",q->arg1);
        fprintf(file,"\tli $v0,1\n");
        fprintf(file,"\tsyscall\n");
        if (q->type == WRITELN_INT)
        {
            fprintf(file,"\tli $v0,4\n");
            fprintf(file,"\tla $a0,line\n");
            fprintf(file,"\tsyscall\n");
        }
    }
    else if (q->type == ALLOC)
    {
        fprintf(file,"#allocation du machin à l'emplacement %d\n",q->res);
        fprintf(file,"\tsub $sp,$sp,4\n");
    }
    else if (q->type == CST)
    {
        fprintf(file,"#affectation CST\n");
        fprintf(file,"\tli $t0,%d\n",q->cst);
	    fprintf(file,"\tsw $t0,%d($sp)\n",q->res);
    }
    else if (q->type == OP_ADD)
    {
        fprintf(file,"#addition\n");
        fprintf(file,"\tlw $t1,%d($sp)\n",q->arg1);
        fprintf(file,"\tlw $t2,%d($sp)\n",q->arg2);
        fprintf(file,"\tadd $t0,$t1,$t2\n");
        fprintf(file,"\tsw $t0,%d($sp)\n",q->res);
    }
    else if (q->type == OP_SUB)
    {
        fprintf(file,"#soustraction\n");
        if (q->arg1 != -1)
        {
            fprintf(file,"\tlw $t1,%d($sp)\n",q->arg1);
        }
        else //On fait un - unaire
        {
            fprintf(file,"\tli $t1,0\n");
        }
        fprintf(file,"\tlw $t2,%d($sp)\n",q->arg2);
        fprintf(file,"\tsub $t0,$t1,$t2\n");
        fprintf(file,"\tsw $t0,%d($sp)\n",q->res);
    }
    else if (q->type == OP_MUL)
    {
        fprintf(file,"#multiplication\n");
        fprintf(file,"\tlw $t1,%d($sp)\n",q->arg1);
        fprintf(file,"\tlw $t2,%d($sp)\n",q->arg2);
        fprintf(file,"\tmul $t0,$t1,$t2\n");
        fprintf(file,"\tsw $t0,%d($sp)\n",q->res);
    }
    else if (q->type == OP_DIV)
    {
        fprintf(file,"#division\n");
        fprintf(file,"\tlw $t1,%d($sp)\n",q->arg1);
        fprintf(file,"\tlw $t2,%d($sp)\n",q->arg2);
        fprintf(file,"\tdiv $t0,$t1,$t2\n");
        fprintf(file,"\tsw $t0,%d($sp)\n",q->res);
    }
    else if (q->type == READ)
    {
    	fprintf(file,"#read\n");
    	fprintf(file,"\tli $v0,5\n");
    	fprintf(file,"\tsyscall\n");
    	fprintf(file,"\tsw $v0,%d($sp)\n",q->arg1);
    }
    else if (q->type == AFFECT)
    {
        fprintf(file,"#affectation\n");
        fprintf(file,"\tlw $t0,%d($sp)\n",q->arg1);
	    fprintf(file,"\tsw $t0,%d($sp)\n",q->res);
    }
    else if (q->type == AFFECT_REGISTRE)
    {
        fprintf(file,"#affectation registre\n");
        fprintf(file,"\tlw $t%d,%d($sp)\n",q->res,q->arg1);
    }
    else if (q->type == STOCK_REGISTRE)
    {
        fprintf(file,"#stock registre\n");
        fprintf(file,"\tsw $t%d,%d($sp)\n",q->res,q->arg1);
    }
    else if (q->type == FREE)
    {
        fprintf(file,"#free\n");
        fprintf(file,"\tadd $sp,$sp,%d\n",q->cst);
    }
    else if (q->type == IFGOTO)
    {
        fprintf(file,"#ifgoto\n");
        if (q->arg1 != -1)
        {
            fprintf(file,"\tlw $t0,%d($sp)\n",q->arg1);
        }
        fprintf(file,"\tbeq $t0,0,l%d\n",q->res);
    }
    else if (q->type == GOTO)
    {
        fprintf(file,"#goto\n");
        fprintf(file,"\tj l%d\n",q->res);
    }
    else if (q->type == COMP_EGAL)
    {
        fprintf(file,"#op =\n");
        fprintf(file,"\tbeq $t1,$t2,l%d\n",q->res);
    }
    else if (q->type == COMP_INF)
    {
        fprintf(file,"#op <\n");
        fprintf(file,"\tblt $t1,$t2,l%d\n",q->res);
    }
    else if (q->type == COMP_SUP)
    {
        fprintf(file,"#op >\n");
        fprintf(file,"\tbgt $t1,$t2,l%d\n",q->res);
    }
    else if (q->type == COMP_INF_EGAL)
    {
        fprintf(file,"#op <=\n");
        fprintf(file,"\tble $t1,$t2,l%d\n",q->res);
    }
    else if (q->type == COMP_SUP_EGAL)
    {
        fprintf(file,"#op >=\n");
        fprintf(file,"\tbge $t1,$t2,l%d\n",q->res);
    }
    else if (q->type == COMP_NOT_EGAL)
    {
        fprintf(file,"#op !=\n");
        fprintf(file,"\tbne $t1,$t2,l%d\n",q->res);
    }
    else if (q->type == APPELFONCTION)
    {
        fprintf(file,"#Appel de fonction\n");
        fprintf(file,"\tjal f%d\n",q->arg1);
    }
    else if (q->type == RETURN)
    {
		fprintf(file,"#Retour de fonction\n");
        fprintf(file,"\tjal $ra\n");
	}
	else if (q->type == PLACER_ARG)
    {
		fprintf(file,"#Arguments de fonctions\n");
        fprintf(file,"\tlw $t0,%d($sp)\n",q->arg1);
	    fprintf(file,"\tsw $t0,0($sp)\n");
	}
}

/* Segment DATA */
int ajouterString(char* text)
{
    s_cell* s =  malloc(sizeof(s_cell));
    s->string = text;
    s->next = NULL;
    if (strings == NULL)
    {
        strings = malloc(sizeof(s_list_cell));
        s->index = 0;
        strings->first = s;
        strings->last = s;
    }
    else
    {
        strings->last->next = s;
        s->index = strings->last->index+1;
        strings->last = s;
    }
    /*char* res;
    res = malloc(sizeof(char)*(7)); //TODO Trouver la bonne taille
    memset(res,'\0',7);//TODO Trouver la bonne taille
    sprintf(res,"str%d",s->index);*/
    return s->index;
}
/* Fonction qui détruit la liste passé en paramètre */
void detruireList(s_list_cell* l)
{
    s_cell* cell, *previous;
    if (l != NULL)
    {
        cell = l->first;
        while (cell!=NULL)
        {
            previous = cell;
            cell = cell->next;
            if (previous->string != NULL)
            {
                free(previous->string);
            }
            free(previous);
        }
        free(l);
    }
}


/* Segment TEXT */
/*
    Ajoute à la file du segment TEXT
    type : opérateur
    arg1 : opérande 1
    arg2 : opérande 2
    res : résultat
*/

s_quad* gen(int type, s_symbole* arg1, s_symbole* arg2, s_symbole* res)
{
    printf("Appel gen() avec type=%d\n",type);
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    if (arg1 == NULL) q->arg1=-1;else q->arg1 = arg1->offset;
    if (arg2 == NULL) q->arg2=-1;else q->arg2 = arg2->offset;
    if (res == NULL) q->res=-1;else q->res = res->offset;
    q->cst = -1;
    ajouterALaListeDeQuadActuelle(q);
    return q;
}
void genString(int type, int index)
{
    printf("Appel genString() avec type=%d\n",type);
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->arg1 = index;
    q->arg2 = -1;
    q->res = -1;
    ajouterALaListeDeQuadActuelle(q);
}
void genCST(int type, int cst, s_symbole* res)
{
    printf("Appel genCST() avec type=%d\n",type);
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = cst;
    q->arg1 = -1;
    q->arg2 = -1;
    q->res = res->offset;
    ajouterALaListeDeQuadActuelle(q);
}
void genGoto(int type, int label)
{
    printf("genGOTO()\n");
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = -1;
    q->arg1 = -1;
    q->arg2 = -1;
    q->res = label;
    ajouterALaListeDeQuadActuelle(q);
}
s_quad* genIfGoto(int type, s_symbole* arg1, int label)
{
    printf("genIFGOTO()\n");
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = -1;
    q->arg1 = arg1->offset;
    q->arg2 = -1;
    q->res = label;
    ajouterALaListeDeQuadActuelle(q);
    return q;
}
void genFREE(int type, int cst)
{
    printf("genFREE()\n");
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = cst;
    q->arg1 = -1;
    q->arg2 = -1;
    q->res = -1;
    ajouterALaListeDeQuadActuelle(q);
}
void genAffectResgistre(int type,s_symbole* arg1, int registre)
{
    printf("genAFFECTREGISTRE()\n");
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = -1;
    q->arg1 = arg1->offset;
    q->arg2 = -1;
    q->res = registre;
    ajouterALaListeDeQuadActuelle(q);
}
void genStockResgistre(int type,s_symbole* arg1, int registre)
{
    printf("genSTOCKREGISTRE()\n");
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = -1;
    q->arg1 = arg1->offset;
    q->arg2 = -1;
    q->res = registre;
    ajouterALaListeDeQuadActuelle(q);
}
void genAppelFonction(int type, s_fonction* fonct)
{
	printf("genAppelFonction()\n");
    s_quad* q = malloc(sizeof(s_quad));
    q->type = type;
    q->cst = -1;
    q->arg1 = fonct->index;
    q->arg2 = -1;
    q->res = -1;
    ajouterALaListeDeQuadActuelle(q);
}
void ajouterALaListeDeQuadActuelle(s_quad* q)
{
	if (fct_en_cours == NULL)
	{
		quads = ajouterALaListeDeQuad(quads,q,1);
	}
	else
	{
		fct_en_cours->quads = ajouterALaListeDeQuad(fct_en_cours->quads,q,1);
	}
}
/* Ajouter un quad à la fin de la liste de quad */
s_list_quad* ajouterALaListeDeQuad(s_list_quad* listquads,s_quad* q, int aNumeroter)
{
    s_quadnext* qn;
    qn = (s_quadnext*)malloc(sizeof(s_quadnext));
    qn->q = q;
    qn->next = NULL;
    if (listquads == NULL)
    {
        if (aNumeroter)
        {   //dans la liste principale ou dans une fonction, on numérote les quads
			qn->q->index = 1;
        }
        //DEBUG
        else
        {
            printf("Rajout de l'instruction %d à une liste.\n",qn->q->index);
        }
        
        listquads = malloc(sizeof(s_list_quad));
        listquads->first = qn;
        listquads->last = qn;
    }
    else
    {
        if (aNumeroter)
        {   //dans la liste principale, on numérote les quads
            qn->q->index = listquads->last->q->index+1;
        }
        //DEBUG
        else
        {
            printf("Rajout de l'instruction %d à une liste.\n",qn->q->index);
        }
        
        listquads->last->next = qn;
        listquads->last = qn;
    }
    return listquads;
    
}

void complete(s_list_quad* list, int label)
{
    printf("Complete avec %d\n",label);
    if (list != NULL)
    {
        s_quadnext* qn = list->first;
        while (qn != NULL)
        {
            printf("Rajout du label %d à l'instruction %d\n", label, qn->q->index);
            qn->q->res = label;
            qn = qn->next;
        }
    }
}
s_list_quad* concat(s_list_quad* list1, s_list_quad* list2)
{
    if (list1 == NULL)
    {
        return list2;
    }
    else if (list2 == NULL)
    {
        return list1;
    }
    else
    {
        list1->last->next = list2->first;
        list1->last = list2->last;
        return list1;
    }
}

/* Liste temporaire pour la déclaration de variables */
s_list_cell* rajouterList(s_list_cell* list,char *id)
{
    s_list_cell* res;
    s_cell* rajout;
    rajout = (s_cell*)malloc(sizeof(s_cell));
    rajout -> string = id;
    rajout -> next = NULL;

    if (list == NULL)
    {
        res = (s_list_cell*)malloc(sizeof(s_list_cell));
        res -> first = rajout;
    }
    else
    {
        res = list;
        res -> last -> next = rajout;
    }

    res -> last = rajout;
    return res;
}





/* Transforme le nom du ficher d'entrée en nom de fichier pour la sortie */
char* outFile(char* inputFileName)
{
    int longueur;
    char* outputFileName;
    
    longueur = strlen(inputFileName)-4;//fichier.scalpa ==> fichier.s
    outputFileName = malloc(sizeof(char)*longueur);
    memset(outputFileName,'\0',longueur);
    
    int i=0;
    while (inputFileName[i]!='.' && i<longueur)
    {
        outputFileName[i]=inputFileName[i];
        i++;
    }
    outputFileName[i]='.';
    outputFileName[i+1]='s';
    
    //printf("[%s]->[%s]\n",inputFileName,outputFileName);TODO:delete cette ligne
    return outputFileName;
}

char* intToString(int num)
{
    char* buf;
    buf = malloc(sizeof(char)*9);
    memset(buf,'\0',9);
    //sprintf(buf, "\"%i\"", num);
    sprintf(buf, "%i", num);
    return buf;
}

/* Ajoute la liste de nom de variable dans la table des symboles */
void ajouterListeSymbole(s_list_cell* list_id, int type, int genererAllocation)
{
    //printf("TYPE : %d\n",type);
    s_cell* id = list_id->first;
    s_symbole* new_s;
    s_symbole* s;
	s_table* tab;
    while (id != NULL)
    {
        if (place(id->string, 0)!=NULL)
        {
            printf("Erreur : Variable %s déclarée 2 fois.\n", id->string);
            exit(-1);
        }
        else
        {
            //new-s : nouvel element à ajouter
            new_s = (s_symbole*)malloc(sizeof(s_symbole));
            new_s->name = strdup(id->string);
            new_s->type = type;
            new_s->next = NULL;
            if (fct_en_cours == NULL)
            {
				tab = tab_symb;
			}
			else
			{
				tab = fct_en_cours->tab_symb_locale;
			}
            if (tab != NULL)
            {
                //pas le premier element de la liste
                
                
                //je parcours toute la liste pour augmenter le offset de 4
                s = tab->first;
                while (s != NULL)
                {
                    s->offset = s->offset+4;
                    s = s->next;
                }
                if (fct_en_cours != NULL && tab_symb != NULL)
                {
					//Je parcours aussi la table des symboles principale
					s = tab_symb->first;
					while (s != NULL)
					{
						printf("ajouter liste symb, On déplace %s de 4 ça donne %d \n", s->name,s->offset + 4 );
						s->offset = s->offset+4;
						s = s->next;
					}
				}
                
                
                new_s->index = tab->last->index + 1;
                new_s->offset = 0;
                tab->last->next = new_s;
                tab->last = new_s;
            }
            else
            {
                //premier élément de la liste
                new_s->index = 0;
                new_s->offset = 0;
                if (fct_en_cours == NULL)
				{
					tab_symb = (s_table*)malloc(sizeof(s_table));
					tab = tab_symb;
				}
				else
				{
					fct_en_cours->tab_symb_locale = (s_table*)malloc(sizeof(s_table));
					tab = fct_en_cours->tab_symb_locale;
				}
				if (fct_en_cours != NULL && tab_symb != NULL)
                {
					//Je parcours aussi la table des symboles principale
					s = tab_symb->first;
					while (s != NULL)
					{
						printf("ajouter liste symb, On déplace %s de 4 ça donne %d \n", s->name,s->offset + 4 );
						s->offset = s->offset+4;
						s = s->next;
					}
				}
                tab->first = new_s;
                tab->last = new_s;
            }
            if (genererAllocation)
            {
				gen(ALLOC,NULL,NULL,new_s);
			}
        }
        id = id -> next;//on parcours la liste des elements à ajouter
    }

    detruireList(list_id);
}
/* crée une varibale temporaire dans la table des symboles */
s_symbole* newtemp()
{
    printf("newtemp()\n");
    s_symbole* new_s;
    s_table* tab;
    
    new_s = (s_symbole*)malloc(sizeof(s_symbole));
    new_s->name = "_temp";
    new_s->type = TYPE_INT;
    new_s->next = NULL;
    
    if (fct_en_cours == NULL)
    {
		tab = tab_symb;
	}
	else
	{
		tab = fct_en_cours->tab_symb_locale;
	}
    
    if (tab != NULL)
    {
        //pas le premier element de la liste
        
        new_s->index = tab->last->index + 1;
        new_s->offset = 0;
        tab->last->next = new_s;
        tab->last = new_s;
    }
    else
    {
        //premier élément de la liste
        new_s->index = 0;
        new_s->offset = 0;
        tab = (s_table*)malloc(sizeof(s_table));
        tab->first = new_s;
        tab->last = new_s;
    }
    
    gen(ALLOC,NULL,NULL,new_s);
    
    deplacerOffset(tab, 4);
    if (fct_en_cours != NULL)
    {
		deplacerOffset(tab_symb, 4);
	}
	
	new_s->offset = 0;
    
    return new_s;
}

void deplacerOffset(s_table* tab, int depl)
{
	s_symbole* s;
	if (tab != NULL)
	{
		s = tab->first;
		while (s != NULL)
		{
			printf("On déplace %s de 4 ça donne %d \n", s->name,s->offset + depl );
			s->offset = s->offset + depl;
			s = s->next;
		}
	}
}

/* Renvoie le symbole qui s'appelle 'name' */
s_symbole* place(char* name, int chercherDansGlobal)
{
    s_symbole* s;
    s_symbole* res = NULL;
    
    if (fct_en_cours != NULL)
    {
		s_table* tab_locale = fct_en_cours->tab_symb_locale;
		if (tab_locale != NULL)
		{
			s = tab_locale->first;
			while (res == NULL && s != NULL)
			{
				if (s->name != NULL && strcmp(s->name,name)==0)
				{
					res=s;
				}
				s = s->next;
			}
		}
	}
	if (res == NULL && chercherDansGlobal)
	{
		if (tab_symb == NULL || tab_symb->first == NULL)
		{
			return NULL;
		}
		s = tab_symb->first;
		while (res == NULL && s != NULL)
		{
			if (s->name != NULL && strcmp(s->name,name)==0)
			{
				res=s;
			}
			s = s->next;
		}
	}
    return res;
}


void ecrireTableSymbole2()// TODO : juste pour les tests -- à supprimer à la fin
{
    s_symbole* s;
    if (tab_symb != NULL)
    {
        s = tab_symb->first;
        printf("[Nom]-[index]-[offset]\n");
        while (s != NULL)
        {
            printf("[%s]-[%d]-[%d]\n",s->name,s->index,s->offset);
            s = s->next;
        }
    }
}

void supprimerSymbole(s_symbole * aSupprimer)
{
    s_symbole* s;
    s_symbole* previous;
    
    if (tab_symb != NULL)
    {
        previous = tab_symb->first;
        s = previous->next;
        while (s != NULL)
        {
            if (s == aSupprimer)
            {
                previous->next = s->next;
                free(s);
                break;
            }
            else 
            {
                s->offset = s->offset - 4;
                previous = s;
                s = s->next;
            }
        }
        tab_symb->last = previous;
    }
}

void freeAlltmp()
{
    s_symbole* s;
    s_symbole* previous;
    int nbRemove=0;
    
    if (tab_symb != NULL)
    {
        previous = tab_symb->first;
        s = previous->next;
        while (s != NULL)
        {
            if (strcmp(s->name,"_temp")==0)
            {
                previous->next = s->next;
                free(s);
                nbRemove++;
                s = previous->next;
            }
            else 
            {
                previous = s;
                s = s->next;
            }
        }
        tab_symb->last = previous;
        
        if (nbRemove > 0)
        {
            genFREE(FREE, nbRemove*4);
        }
        
        s = tab_symb->first;
        while (s != NULL)
        {
            if (s->offset >= 0)
            {
                s->offset = s->offset - (4 * nbRemove);
            }
            s = s->next;
        }
    }
}

int verifType(int type, s_expr expr1, s_expr expr2)
{
    int res;
    if (type == TYPE_INT)
    {
        res = expr1.symbole != NULL
                && expr1.symbole->type == TYPE_INT
                && expr2.symbole != NULL
                && expr2.symbole->type == TYPE_INT;
    } else if (type == TYPE_BOOL)
    {
        res = expr1.symbole == NULL 
                && expr2.symbole == NULL;
    }
    return res;
}

s_fonction* newFct(char* nom)
{
    s_fonction* new_fct = (s_fonction*)malloc(sizeof(s_fonction));
    new_fct->name = nom;
    new_fct->index = indexFonction++;
	s_symbole* new_s;
	if (place(nom,1)!=NULL)
	{
        printf("Erreur : Variable %s déclarée 2 fois.\n", nom);
		exit(-1);
	}
	else
	{
		new_s = (s_symbole*)malloc(sizeof(s_symbole));
        new_s->name = strdup(nom);
        new_s->type = TYPE_FONCTION;
        new_s->next = NULL;
        new_s->fonction = new_fct;
        
            if (tab_symb != NULL)
            {
                //pas le premier element de la liste
                
                new_s->index = tab_symb->last->index+1;
                new_s->offset = 0;
                tab_symb->last->next = new_s;
                tab_symb->last = new_s;
            }
            else
            {
                //premier élément de la liste
                new_s->index = 0;
                new_s->offset = 0;
				tab_symb = (s_table*)malloc(sizeof(s_table));

                tab_symb->first = new_s;
                tab_symb->last = new_s;
            }
		}
	
    return new_fct;
}

void supprimerTable_locale(s_fonction* fct, int changerOffest)
{
	s_symbole* s;
	int nbRemove = 0;
	if (fct->tab_symb_locale != NULL)
	{
		s = fct->tab_symb_locale->first;
		while (s != NULL)
		{
			nbRemove++;
			s = s->next;
		}
	}
	if (nbRemove > 0)
	{
		genFREE(FREE, 4*nbRemove);
		if (tab_symb != NULL && changerOffest)
		{
			//pas le premier element de la liste
			
			//je parcours toute la liste pour reduire le offset
			s = tab_symb->first;
			while (s != NULL)
			{
				if (s->offset >= 0)
				{
					s->offset = s->offset-4*nbRemove;
					printf("Je reduit le offset de %s ca donne %d\n",s->name, s->offset);
				}
				s = s->next;
			}
		}
	}
}
